<template>
  <div id="relate-echart" ref="chartRef"></div>
</template>

<script lang="ts" setup>
import * as echarts from "echarts/core";
import { GraphChart } from "echarts/charts";
import { H5SharegetKlidName } from "@/api/h5layout";
import {
  TitleComponent,
  TooltipComponent,
  GridComponent,
  DatasetComponent,
  TransformComponent,
  LegendComponent,
} from "echarts/components";
import { LabelLayout, UniversalTransition } from "echarts/features";
import { CanvasRenderer } from "echarts/renderers";
import type { GraphSeriesOption } from "echarts/charts";
import type {
  TitleComponentOption,
  TooltipComponentOption,
  GridComponentOption,
  DatasetComponentOption,
  LegendComponentOption,
} from "echarts/components";
import type { ComposeOption } from "echarts/core";
import { onMounted, ref, onBeforeUnmount } from "vue";

// 注册必须的组件
echarts.use([
  TitleComponent,
  TooltipComponent,
  GridComponent,
  DatasetComponent,
  TransformComponent,
  GraphChart,
  LabelLayout,
  UniversalTransition,
  CanvasRenderer,
  LegendComponent,
]);

// 定义组合Option类型
type ECOption = ComposeOption<
  | GraphSeriesOption
  | TitleComponentOption
  | TooltipComponentOption
  | GridComponentOption
  | DatasetComponentOption
  | LegendComponentOption
>;

// 定义类型
interface GraphNode {
  KlID: string;
  KlName: string;
}

interface NodeData {
  name: string;
  id: string;
  pointIdName: string;
  pointId: string;
  isOpen?: boolean;
  parentPointId: string;
  deep: number;
  symbolSize?: number;
  itemStyle?: {
    color?: string;
    borderColor?: string;
    borderWidth?: number;
    opacity?: number;
  };
  x?: number;
  y?: number;
  fixed?: boolean;
}

interface LinkData {
  source: string;
  target: string;
  lineStyle: {
    width: number;
    curveness: number;
    color?: string;
  };
}

// 图表引用
const chartRef = ref<HTMLElement | null>(null);
let chartObj: echarts.ECharts | null = null;

// 节点状态管理
const nodeStates = ref<
  Record<string, { isOpen: boolean; children?: string[] }>
>({});

// ID生成器
let idCounter = 100; // 从100开始，避免与根节点冲突

const generateId = (parentId: string, index: number) => {
  return `${parentId}-${index}`;
};
const props = defineProps<{
  echartsdata: GraphNode[];
}>();
// 初始化图表
const initChart = () => {
  if (!chartRef.value) return;

  chartObj = echarts.init(chartRef.value);
  const option = initRelateCharts();
  chartObj.setOption(option);
  renderLevel1();
  bindChartEvents();
};

// 根节点数据
const rootNodes: GraphNode[] = [{ KlID: "111", KlName: "" }];

// 初始化图表配置
const initRelateCharts = (): ECOption => {
  const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
  return {
    title: {
      text: "",
      left: "center",
    },
    tooltip: {
      trigger: "item",
      formatter: "{b}",
    },
    legend: {
      data: [],
      orient: "vertical",
      right: 10,
      top: "center",
    },
    animation: false,
    series: [
      {
        type: "graph",
        layout: "force",
        roam: true,
        data: [],
        links: [],
        label: {
          show: true,
          position: "top",
          formatter: "{b}",
          fontStyle: "400",
          fontSize: 14,
          color: "#4A4A4A",
        },
        emphasis: {
          focus: "adjacency",
          label: {
            show: true,
          },
        },
        focusNodeAdjacency: false,
        force: {
          repulsion: 650,
          edgeLength: isMobile? 30 : 120, // 根据设备类型设置连接线长度
        },
      },
    ],
  };
};

// 渲染第一层数据
const renderLevel1 = () => {
  // 初始化节点状态
  rootNodes.forEach((node) => {
    nodeStates.value[node.KlID] = { isOpen: false };
  });

  const nodes = regroupData(rootNodes, 1, "111"); // 根节点ID改为实际的"111"
  
  redrawGraph(nodes.nodesList, nodes.nodesRelates);
};

// 重组数据
const regroupData = (list: GraphNode[], deep: number, parentId: string) => {
  const nodesList: NodeData[] = [];
  const nodesRelates: LinkData[] = [];
 // 判断是否是手机设备（简单示例，可根据实际需求优化）
 const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);

  list.forEach((data, index) => {
    const id = data.KlID;
    const name = data.KlName;
    const nodeObj: NodeData = {
      name,
      id,
      pointIdName: name,
      pointId: id,
      parentPointId: parentId,
      deep,
      isOpen: nodeStates.value[id]?.isOpen || false,
      symbolSize: id === "111" ? 20 : isMobile ? 40 - (1 + deep / 5) * 7 : 80 - (1 + deep / 5) * 14,
      
      itemStyle: {
        color: setColorItem(deep),
        ...(id === "111"
          ? {
              borderColor: "rgba(52,186,232,0.30)",
              borderWidth: 12,
            }
          : {}),
      },
    };

    nodesList.push(nodeObj);

    if (id !== "111") {
      nodesRelates.push({
        source: parentId,
        target: id,
        lineStyle: {
          width: isMobile ? 0.5 : 1,
          curveness: 0.1,
          color: setColorItem(deep),
        },
      });
    }
  });

  return { nodesList, nodesRelates };
};

// 重绘图表
const redrawGraph = (nodes: NodeData[], links: LinkData[]) => {
  if (!chartObj) return;

  const option = chartObj.getOption() as ECOption;
  const series = option.series?.[0] as GraphSeriesOption | undefined;

  if (series) {
    series.data = nodes;
    series.links = links;
   
    chartObj.setOption(option, { notMerge: true });
  }
};

// 获取当前节点列表
const getCurrentNodes = () => {
  if (!chartObj) return { sData: [], links: [] };

  const option = chartObj.getOption() as ECOption;
  const series = option.series?.[0] as GraphSeriesOption | undefined;

  return {
    sData: (series?.data as NodeData[]) || [],
    links: (series?.links as LinkData[]) || [],
  };
};

// 处理节点点击
const handleNodeClick = async (nodeInfo: NodeData) => {
  if (!nodeInfo) return;

  // 根节点特殊处理（这里假设"111"是根节点ID）
  if (nodeInfo.pointId === "111") {
    restoreInitialState(nodeInfo);
    return;
  }

  const currentNodeState = nodeStates.value[nodeInfo.pointId] || {
    isOpen: false,
  };

  if (currentNodeState.isOpen) {
    // 关闭节点
    await collapseNode(nodeInfo);
  } else {
    // 打开节点
    await expandNode(nodeInfo);
  }
};

// 展开节点
const expandNode = async (nodeInfo: NodeData) => {
  // 关闭同层其他已打开的节点
  const sameLevelNodes = Object.entries(nodeStates.value).filter(
    ([id, state]) =>
      state.isOpen &&
      id !== nodeInfo.pointId &&
      getNodeDepth(id) === nodeInfo.deep
  );

  for (const [id] of sameLevelNodes) {
    const nodeData = findNodeData(id);
    if (nodeData) await collapseNode(nodeData);
  }

  // 更新节点状态
  nodeStates.value[nodeInfo.pointId].isOpen = true;
  updateNodeStyle(nodeInfo, true);

  // 加载子节点数据
  const childData = await fetchChildNodes(nodeInfo);
  if (childData && childData.length > 0) {
    const newNodesList = regroupData(
      childData,
      nodeInfo.deep + 1,
      nodeInfo.pointId
    );

    // 记录子节点ID
    nodeStates.value[nodeInfo.pointId].children = newNodesList.nodesList.map(
      (n) => n.pointId
    );

    // 初始化子节点状态
    newNodesList.nodesList.forEach((node) => {
      nodeStates.value[node.pointId] = { isOpen: false };
    });

    // 添加新节点和连接
    const { sData, links } = getCurrentNodes();
   
    redrawGraph(
      [...sData, ...newNodesList.nodesList],
      [...links, ...newNodesList.nodesRelates]
    );
  }
};

// 折叠节点
const collapseNode = async (nodeInfo: NodeData) => {
  // 更新节点状态
  nodeStates.value[nodeInfo.pointId].isOpen = false;
  updateNodeStyle(nodeInfo, false);

  // 删除子节点
  const children = nodeStates.value[nodeInfo.pointId].children || [];
  const { sData, links } = getCurrentNodes();

  // 递归删除所有子节点
  const nodesToRemove = new Set<string>();
  const linksToRemove = new Set<string>();

  const collectChildren = (parentId: string) => {
    const children = nodeStates.value[parentId]?.children || [];
    children.forEach((childId) => {
      nodesToRemove.add(childId);
      linksToRemove.add(`${parentId}-${childId}`);

      // 递归收集子节点的子节点
      if (nodeStates.value[childId]?.children) {
        collectChildren(childId);
      }

      // 删除子节点状态
      delete nodeStates.value[childId];
    });

    // 清空子节点引用
    delete nodeStates.value[parentId].children;
  };

  collectChildren(nodeInfo.pointId);

  // 过滤节点和连接
  const newNodes = sData.filter((node) => !nodesToRemove.has(node.pointId));
  const newLinks = links.filter(
    (link) => !linksToRemove.has(`${link.source}-${link.target}`)
  );


  redrawGraph(newNodes, newLinks);
};

// 恢复初始状态
const restoreInitialState = (nodeInfo: NodeData) => {
  // 重置所有节点状态
  Object.keys(nodeStates.value).forEach((id) => {
    if (id !== "111") {
      nodeStates.value[id].isOpen = false;
      delete nodeStates.value[id].children;
    }
  });

  // 只保留第一层节点
  const { sData } = getCurrentNodes();
  const rootNodesData = sData.filter((node) => node.deep <= 1);
  const rootLinks = rootNodesData
    .filter((node) => node.pointId !== "111")
    .map((node) => ({
      source: "111",
      target: node.pointId,
      lineStyle: { width: 1, curveness: 0.1, color: setColorItem(1) },
    }));

 
  redrawGraph(rootNodesData, rootLinks);
};

// 更新节点样式
const updateNodeStyle = (node: NodeData, isOpen: boolean) => {
  const { sData } = getCurrentNodes();
  const nodeToUpdate = sData.find((n) => n.pointId === node.pointId);

  if (nodeToUpdate) {
    nodeToUpdate.itemStyle = {
      color: isOpen ? "#ff0000" : setColorItem(node.deep),
      borderColor: isOpen ? "rgba(255,0,0,0.3)" : undefined,
    };
  }
};

// 查找节点数据
const findNodeData = (id: string): NodeData | null => {
  const { sData } = getCurrentNodes();
  return sData.find((node) => node.pointId === id) || null;
};

// 获取节点深度
const getNodeDepth = (id: string): number => {
  const node = findNodeData(id);
  return node ? node.deep : -1;
};

// 模拟获取子节点数据 - 根据点击的节点动态生成
const fetchChildNodes = async (nodeInfo: NodeData): Promise<GraphNode[]> => {
  return new Promise((resolve) => {
   
    H5SharegetKlidName({ klid: Number(nodeInfo.pointId.split('-')[0]) }).then((res: any) => {
      const children: GraphNode[] = [];
      for (let i = 0; i < res.length; i++) {
        children.push({
          KlID: generateId(res[i].KlID, i),
          KlName: `${res[i].KlName}`,
        });
      } 
      resolve(children);
    });
    // setTimeout(() => {
    //   const childCount = Math.floor(Math.random() * 3) + 2; // 随机2-4个子节点
    //   const children: GraphNode[] = [];

    //   for (let i = 0; i < childCount; i++) {
    //     children.push({
    //       KlID: generateId(nodeInfo.pointId, i),
    //       KlName: `${nodeInfo.name}-子节点${i + 1}`,
    //     });
    //   }


    // }, 300);
  });
};

// 设置节点颜色
const setColorItem = (deep: number) => {
  const deepColor = ["#34BAE8", "#91cc75", "#9ad940", "#ffc600", "#ff8986"];
  return deepColor[deep] || "#34BAE8";
};

// 绑定图表事件
const bindChartEvents = () => {
  if (!chartObj) return;

  chartObj.off("click");
  chartObj.on("click", async (params: any) => {
    try {
      const nodeInfo = params.data as NodeData;
      await handleNodeClick(nodeInfo);
    } catch (error) {
      console.error("处理节点点击时出错:", error);
      // 恢复图表到稳定状态
      if (chartObj) {
        const option = chartObj.getOption();
        chartObj.setOption(option, true);
      }
    }
  });
};

// 窗口大小变化时调整图表大小
const handleResize = () => {
  chartObj?.resize();
};

// 组件生命周期
onMounted(() => {
  props.echartsdata.forEach((item: any) => {
    if (
      item &&
      typeof item.KlID === "string" &&
      typeof item.KlName === "string"
    ) {
      rootNodes.push(item);
    }
  });
 
  initChart();
  window.addEventListener("resize", handleResize);
});

onBeforeUnmount(() => {
  if (chartObj) {
    chartObj.dispose();
    chartObj = null;
  }
  window.removeEventListener("resize", handleResize);
});
</script>

<style scoped>
#relate-echart {
  width: 100%;
  height: 100%;
  margin: 0 auto;
}
</style>
